package com.xzj.admin.boot.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.xzj.admin.base.constants.BaseConstants;
import com.xzj.admin.base.domain.gateway.XzjRouterConfigDefinition;
import com.xzj.admin.boot.domain.entity.SysGatewayRouter;
import com.xzj.admin.boot.handle.RedisHandle;
import com.xzj.admin.boot.mapper.SysGatewayRouterMapper;
import com.xzj.admin.boot.service.SysGatewayRouterService;
import com.xzj.common.datasource.domain.PageReq;
import com.xzj.common.datasource.domain.PageResp;
import com.xzj.common.datasource.utils.XzjPageUtil;
import com.xzj.common.id.gen.DefaultIdHelper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @program: xzj-admin
 * @ClassName: SysGatewayRouterServiceImpl
 * @description: 网关路由管理;(sys_gateway_router)表服务实现类
 * @author: XiaZunJun
 * @create: 2024-10-12 14:30
 */
@Service
@Slf4j
public class SysGatewayRouterServiceImpl implements SysGatewayRouterService {

    @Resource
    private SysGatewayRouterMapper sysGatewayRouterMapper;

    @Resource
    private RedisTemplate<String,String> redisTemplate;

    @Resource
    private RedisHandle redisHandle;



    @Override
    public PageResp<SysGatewayRouter> pageQuery(PageReq<SysGatewayRouter> pageReq) {
        return XzjPageUtil.queryPage(pageReq, sysGatewayRouter -> {
            List<SysGatewayRouter> sysGatewayRouters = sysGatewayRouterMapper.queryRouters(sysGatewayRouter);
            splitTypeConfig(sysGatewayRouters);
            return sysGatewayRouters;
        });
    }

    private static void splitTypeConfig(List<SysGatewayRouter> sysGatewayRouters) {
        sysGatewayRouters.forEach(router -> {
            for(XzjRouterConfigDefinition definition : router.getRouterConfig()){
                if(definition.getConfigType().equals("filters")){
                    router.getFiltersConfig().add(definition);
                }else{
                    router.getPredicatesConfig().add(definition);
                }
            }
        });
    }

    @Override
    @Transactional
    public void update(SysGatewayRouter sysGatewayRouter) {
        sysGatewayRouterMapper.updateRouter(sysGatewayRouter);
        updateRouterConfig(sysGatewayRouter.getId(), sysGatewayRouter.getFiltersConfig());
        updateRouterConfig(sysGatewayRouter.getId(), sysGatewayRouter.getPredicatesConfig());
        redisHandle.hset(BaseConstants.REDIS_GATEWAY_ROUTER_KEY,sysGatewayRouter.getId(), JSON.toJSONString(sysGatewayRouter));
    }

    private void updateRouterConfig(String routerId, List<XzjRouterConfigDefinition> routerConfigDefinitionList) {
        List<XzjRouterConfigDefinition> addList = new ArrayList<>();
        routerConfigDefinitionList.forEach(definition -> {
            if(StrUtil.isNotEmpty(definition.getRouterConfigId())){
                sysGatewayRouterMapper.updateRouterConfig(definition);
            }else{
                definition.setRouterConfigId(DefaultIdHelper.nextIdStr());
                definition.setRouterId(routerId);
                addList.add(definition);
            }
        });
        if(!addList.isEmpty()){
            sysGatewayRouterMapper.batchInsertRouterConfig(addList);
        }
    }

    @Override
    @Transactional
    public void insert(SysGatewayRouter sysGatewayRouter) {
        sysGatewayRouterMapper.insertRouter(sysGatewayRouter);
        insertRouterConfig(sysGatewayRouter.getId(), sysGatewayRouter.getPredicatesConfig());
        insertRouterConfig(sysGatewayRouter.getId(), sysGatewayRouter.getFiltersConfig());
        redisHandle.hset(BaseConstants.REDIS_GATEWAY_ROUTER_KEY,sysGatewayRouter.getId(),JSON.toJSONString(sysGatewayRouter));
    }

    private void insertRouterConfig(String routerId, List<XzjRouterConfigDefinition> routerConfigDefinitionList) {
        if (!routerConfigDefinitionList.isEmpty()) {
            routerConfigDefinitionList.forEach(x -> {
                x.setRouterConfigId(DefaultIdHelper.nextIdStr());
                x.setRouterId(routerId);
            });
            sysGatewayRouterMapper.batchInsertRouterConfig(routerConfigDefinitionList);
        }
    }

    @Override
    @Transactional
    public boolean deleteById(String id) {
        sysGatewayRouterMapper.deleteRouterConfigs(id);
        sysGatewayRouterMapper.deleteRouterById(id);
        redisHandle.hDel(BaseConstants.REDIS_GATEWAY_ROUTER_KEY,id);
        return false;
    }

    @Override
    @Transactional
    public boolean deleteRouterConfigsById(String id) {
        boolean delFlag =  sysGatewayRouterMapper.deleteRouterConfigsById(id) > 0;
        if(delFlag){
            SysGatewayRouter sysGatewayRouter = new SysGatewayRouter();
            sysGatewayRouter.setId(id);
            List<SysGatewayRouter> sysGatewayRouters = sysGatewayRouterMapper.queryRouters(sysGatewayRouter);
            splitTypeConfig(sysGatewayRouters);
            for(SysGatewayRouter router : sysGatewayRouters){
                redisHandle.hset(BaseConstants.REDIS_GATEWAY_ROUTER_KEY,router.getId(),JSON.toJSONString(router));
            }
        }
        return delFlag;
    }
}
